using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Imaging;
using Microsoft.Practices.ServiceLocation;
using MishraReader.Entities;
using MishraReader.Shell;
using MishraReader.ViewModels;
using MetroLog;
using Ninject;
using CommonServiceLocator.NinjectAdapter;
using MetroLog.Targets;


namespace MishraReader
{
    public partial class App
    {
        private static readonly ILogger Log;


        static App()
        {
            DefaultImage = new BitmapImage(new Uri("/Assets/MishraReader.png", UriKind.Relative));
            var fst = new StreamingFileTarget {PathUnderAppData = "MishraReader"};

            LogManagerFactory.DefaultConfiguration.AddTarget(LogLevel.Trace, LogLevel.Fatal, fst);
            Log = LogManagerFactory.DefaultLogManager.GetLogger<App>();
        }

        protected override void OnExit(ExitEventArgs e)
        {
            SingleInstanceHelper.Cleanup();

            base.OnExit(e);
        }


        protected override void OnStartup(StartupEventArgs e)
        {
            if (!SingleInstanceHelper.InitializeAsFirstInstance())
                Shutdown();

            WireUnhandledExceptionHandlers();

            InitializeCommonServiceLocator();
            
            base.OnStartup(e);

            var fvi = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location);
            Log.Info("MishraReader {0} Startup", fvi.ProductVersion);

            //Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");
            //Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-FR");

            ServiceLocator.Current.GetInstance<IWpfApplication>().Initialize();

            BindingErrorTraceListener.SetTrace();
            
            var window = ServiceLocator.Current.GetInstance<MishraReaderWindow>();
            window.Show();
        }

        public static BitmapSource DefaultImage { get; private set; }

        private static void InitializeCommonServiceLocator()
        {
            var kernel = new StandardKernel(new MishraReaderModule());
            kernel.Load("MishraReader.ViewModels.dll");
            kernel.Load("MishraReader.Entities.dll");
            kernel.Load("MishraReader.ShareService.*.dll");

            var adapter = new NinjectServiceLocator(kernel);
            Microsoft.Practices.ServiceLocation.ServiceLocator.SetLocatorProvider(() => adapter);
            // Inject ISL 
            kernel.Bind<IServiceLocator>().ToConstant(Microsoft.Practices.ServiceLocation.ServiceLocator.Current);
        }

        [Conditional("RELEASE")]
        private void WireUnhandledExceptionHandlers()
        {
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
            Dispatcher.UnhandledException += Dispatcher_UnhandledException;
            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
        }

        void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
        {
            Log.Fatal("Unhandled TaskScheduler Exception", e.Exception);
        }

        void Dispatcher_UnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            Log.Fatal("Unhandled Dispatcher Exception", e.Exception);
        }

        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            Log.Fatal("Unhandled AppDomain Exception", e.ExceptionObject as Exception);
            
        }
        
    }
}